package top.starshine.pack;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * <h1 color="#409EFF"> 系统扫描 class 配置 </h1>
 *
 * @Since: 🫵👁️👁️👉 [ @git/master ][ @date/2025-11-23 ][ @author/Gzh ]
 */
public class SystemScanClassConfig {

    /** 扫描包 */
    private Set<String> scanPackages = new HashSet<>();
    /** 排除包 */
    private Set<String> excludePackages = new HashSet<>();
    /** 包含子包 */
    private boolean includeSubPackages = true;
    /** 编译后的正则表达式模式 - 扫描包 */
    private final Set<Pattern> scanPackagePatterns = new HashSet<>();
    /** 编译后的正则表达式模式 - 排除包 */
    private final Set<Pattern> excludePackagePatterns = new HashSet<>();

    public SystemScanClassConfig () {
    }

    // Getters 和 Setters
    public Set<String> getScanPackages () {
        return scanPackages;
    }

    public void setScanPackages (Set<String> scanPackages) {
        this.scanPackages = scanPackages;
        this.scanPackagePatterns.clear();
        // 编译扫描包模式
        for (String pkg : this.scanPackages) {
            this.scanPackagePatterns.add(compilePackagePattern(pkg));
        }
    }

    public Set<String> getExcludePackages () {
        return excludePackages;
    }

    public void setExcludePackages (Set<String> excludePackages) {
        this.excludePackages = excludePackages;
        this.excludePackagePatterns.clear();
        // 编译排除包模式
        for (String pkg : this.excludePackages) {
            this.excludePackagePatterns.add(compilePackagePattern(pkg));
        }
    }

    public boolean isIncludeSubPackages () {
        return includeSubPackages;
    }

    public void setIncludeSubPackages (boolean includeSubPackages) {
        this.includeSubPackages = includeSubPackages;
    }

    public Set<Pattern> getScanPackagePatterns () {
        return scanPackagePatterns;
    }

    public Set<Pattern> getExcludePackagePatterns () {
        return excludePackagePatterns;
    }


    /**
     * 将包模式转换为正则表达式
     * 支持:
     * - 精确匹配: "com.example.service"
     * - 单级通配符: "com.*.service"
     * - 多级通配符: "com.**.service"
     * - 后缀匹配: "com.example.*"
     */
    private Pattern compilePackagePattern (String packagePattern) {
        if (packagePattern == null || packagePattern.trim().isEmpty()) {
            return Pattern.compile(".*");
        }

        // 转义正则特殊字符，但保留通配符
        String regex = packagePattern
                .replace(".", "\\.")
                .replace("**", ":::DOUBLE_STAR:::")
                .replace("*", ":::SINGLE_STAR:::")
                .replace(":::DOUBLE_STAR:::", ".*")  // ** 匹配多级
                .replace(":::SINGLE_STAR:::", "[^.]+") // * 匹配单级
                .replace("?", "[^.]"); // ? 匹配单个字符

        // 如果模式以 .* 结尾，允许匹配子包
        if (!regex.endsWith(".*") && includeSubPackages && !packagePattern.contains("*") && !packagePattern.contains("?")) {
            regex = regex + "(\\..*)?";
        }

        return Pattern.compile("^" + regex + "$");
    }

    /**
     * 检查包名是否匹配任何扫描模式
     */
    public boolean matchesScanPatterns (String packageName) {
        if (scanPackagePatterns.isEmpty()) {
            return true; // 没有配置扫描包，匹配所有
        }

        for (Pattern pattern : scanPackagePatterns) {
            if (pattern.matcher(packageName).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查包名是否匹配任何排除模式
     */
    public boolean matchesExcludePatterns (String packageName) {
        for (Pattern pattern : excludePackagePatterns) {
            if (pattern.matcher(packageName).matches()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString () {
        return "SystemScanClassConfig{" +
                "scanPackages=" + scanPackages +
                ", excludePackages=" + excludePackages +
                ", includeSubPackages=" + includeSubPackages +
                '}';
    }

}
